import os
import argparse
import json
import urllib.parse
import signal

from . import config
from .rpms import RPM
from .gitee import Gitee

filters = {'os': list(), 'arch': list()}

"""
存储所有页面可以过滤的项
"""
for os_name, params in config.repo_groups.items():
    if not os_name in filters['os']:
        filters['os'].append(os_name)
    
    if 'type' in params and params['type'] == 'rpm':
        for repo, repo_param in params['repos'].items():
            for arch in repo_param.keys():
                if not arch in filters['arch']:
                    filters['arch'].append(arch)

    if 'gitee' in params and not 'gitee' in filters['arch']:
        filters['arch'].append('gitee')


def store_stores(update):
    stores = list()
    gitees = list()

    for os_name, params in config.repo_groups.items():
        print(f"collect {os_name} ...... ", flush=True)

        if 'type' in params and params['type'] == 'rpm':
            workdir = os.path.join(config.workdir, os_name)
            rpm = RPM(workdir, os_name, params['repos'], update)

            stores.append(rpm)

        if 'gitee' in params:
            gparams = params['gitee']
            gitee = Gitee(os_name, gparams['access_token'], gparams['owner'], gparams['sort'], gparams['direction'])
            gitees.append(gitee)

    print("done")

    return stores, gitees


def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--noupdate', action='store_true', help="启动时 不更新repodata")

    known_args, unknown_args = parser.parse_known_args()
    return known_args


# 所有仓库缓存repodata
args = parse_args()
stores, gitees = store_stores(not args.noupdate)


def rebuild():
    """直接退出 依赖 systemdctl restart=Alway 重启"""
    os.kill(os.getpid(), signal.SIGKILL)


def search_default_groups():
    """
    搜索页面默认放置的内容
    仓库信息
    """
    results = dict()

    for os_name, os_param in config.repo_groups.items():
        if 'type' in os_param and os_param['type'] == 'rpm':
            for repo, repo_param in os_param['repos'].items():
                for arch, repo_url in repo_param.items():
                    os_repo = f"{os_name} {repo}"
                    if not os_repo in results:
                        results[os_repo] = dict()
                    if not arch in results[os_repo]:
                        results[os_repo][arch] = list()

                    results[os_repo][arch].append(
                        (repo_url, repo_url, f'{os_name} {repo} {arch} repo url',)
                    )

        if 'gitee' in os_param and not os_param['gitee']['owner'] in results:
            gparam = os_param['gitee']
            results[gparam['owner']] = {
                'gitee' : [
                    (f"https://gitee.com/{gparam['owner']}", f"https://gitee.com/{gparam['owner']}", f"{gparam['owner']} at gitee")
                    ]}

    return results


default_groups = search_default_groups()


def search(target, filter):
    if not target:
        return dict()

    cnt = 0
    pkgids = list()
    results = {}

    try:
        if not 'search' in filter:
            raise OverflowError

        for store in stores:
            if 'os' in filter and not store.os_name in filter['os']:
                continue

            sotres = store.search(target, filter['arch'], filter['search'], config.search_pkg_max - cnt)
            for pkgid, repo, arch, name, summary in sotres:
                if pkgid in pkgids:
                    continue

                pkgids.append(pkgid)

                if not store.os_name in results:
                    results[store.os_name] = dict()

                if not arch in results[store.os_name]:
                    results[store.os_name][arch] = list()

                urlparam = "/rpm?" + urllib.parse.urlencode({
                    'pkgid': pkgid,
                    'repo': repo,
                    'arch': arch,
                    'os_name': store.os_name,
                })
                results[store.os_name][arch].append((urlparam, name, summary))

                cnt += 1
                if cnt >= config.search_pkg_max:
                    raise OverflowError   
    except OverflowError:
        pass

    if not 'arch' in filter or not 'gitee' in filter['arch']:
        return results
    
    for gitee in gitees:
        if 'os' in filter and not gitee.os_name in filter['os']:
            continue
        for pkgid, repo, arch, name, summary in gitee.search(target):
            if not gitee.os_name in results:
                results[gitee.os_name] = dict()

            if not arch in results[gitee.os_name]:
                results[gitee.os_name][arch] = list()

            results[gitee.os_name][arch].append((summary, name, summary))

    return results


def autocomplete(target, filter):
    results = set()
    cnt = 0

    if not target:
        return results

    try:
        for store in stores:
            autocompletes = store.autocomplete(target, filter['arch'], filter['search'], \
                config.autocomplete_max - cnt)
            if autocompletes is None:
                continue

            for result in autocompletes:
                if result in results:
                    continue
                results.add(result)
                
                cnt += 1
                if cnt >= config.autocomplete_max:
                    raise OverflowError

    except OverflowError:
        pass

    return results


def get_pkginfo(arg):
    for store in stores:
        if store.os_name == arg['os_name']:
            pkginfo = store.get_pkginfo(arg['pkgid'], arg['repo'], arg['arch'])

            if not pkginfo is None:
                pkginfo["search_srpm_same_os"] = f"/search?q={pkginfo['info']['name']}&filter=" + \
                    urllib.parse.quote(json.dumps({
                    'os': (store.os_name, ),
                    'arch': ('Source', ),
                    'search': ('Pkg Name', ),
                }))
                pkginfo["search_srpm_all_os"] = f"/search?q={pkginfo['info']['name']}&filter=" + \
                    urllib.parse.quote(json.dumps({
                    'arch': ('Source', ),
                    'search': ('Pkg Name', ),
                }))

                pkginfo["search_gitee_same_os"] = f"/search?q={pkginfo['info']['name']}&filter=" + \
                    urllib.parse.quote(json.dumps({
                    'os': (store.os_name, ),
                    'arch': ('gitee', ),
                }))
                pkginfo["search_gitee_all_os"] = f"/search?q={pkginfo['info']['name']}&filter=" + \
                    urllib.parse.quote(json.dumps({
                    'arch': ('gitee', ),
                }))

            return pkginfo

